package com.nulldev.util.web.flexibleKit.flexRenderer.styling.fonts;

import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import com.nulldev.util.data.Arrays.maps.FastMaps;
import com.nulldev.util.graphics.renderIt.api.renderItGraphicsInterface;
import com.nulldev.util.graphics.renderIt.api.core.RITFont;
import com.nulldev.util.graphics.renderIt.api.envcaps.renderItOperations;
import com.nulldev.util.gui.fontAPI.Font;
import com.nulldev.util.gui.fontAPI.FontManager;

public class flexFontManager {

	public static final int DEFAULT_SIZE = 16;
	public static final int PARAGRAPH_SIZE = DEFAULT_SIZE + 2;
	private static final Map<String, Integer> SIZES = FastMaps.map();
	static {
		if (SIZES.isEmpty()) {
			SIZES.put("default", DEFAULT_SIZE);
			SIZES.put("paragraph", PARAGRAPH_SIZE);
			SIZES.put("strong", PARAGRAPH_SIZE);
			SIZES.put("header", PARAGRAPH_SIZE);
			SIZES.put("listItem", DEFAULT_SIZE);
			SIZES.put("blockQuote", DEFAULT_SIZE);
		}
	}

	public static int getFontSize(final String string) {
		if (string == null || string.isEmpty())
			return DEFAULT_SIZE;
		return SIZES.getOrDefault(string, DEFAULT_SIZE);
	}

	private static final String[] DEFAULT_FONT_SET = new String[]
		{ "BreezeSans", "PreludeWGL Medium", "Prelude Medium", "SF Pro Text", "Open Sans", "Fira Sans", "Lucida Sans", "Lucida Sans Unicode", "Trebuchet MS",
				"Liberation Sans", "Nimbus Sans L", "Arial" };
	private static final String[] CURSIVE_FONT_SET = new String[]
		{ "Comic Sans MS", "Brush Script MT", "Brush Script Std", "Lucida Calligraphy", "Lucida Handwriting", "Apple Chancery" };
	private static final String[] MONOSPACED_FONT_SET = new String[]
		{ "Fira Mono", "DejaVu Sans Mono", "Menlo", "Consolas", "Liberation Mono", "Monaco", "Lucida Console" };
	private static final String[] SERIF_FONT_SET = new String[]
		{ "Lucida Bright", "Lucida Fax", "Palatino", "Palatino Linotype", "Palladio", "URW Palladio", "Times New Roman" };
	private static final String[] FANTASY_FONT_SET = new String[]
		{ "Papyrus", "Herculanum", "Party LET", "Curlz MT", "Harrington", "Impact" };
	private static final String[] EMOJI_FONT_SET = new String[]
		{ "Noto Color Emoji", "Apple Color Emoji", "Twemoji Awesome", "Segoe MDL2 Assets" };
	private static final Map<String, Font> FONTS = FastMaps.map();

	static {
		if (FONTS.isEmpty()) {
			FONTS.put("--flexKit-fallback", FontManager.getFontSet());
			FONTS.put("default", FontManager.gets(DEFAULT_FONT_SET));
			FONTS.put("sans-serif", FontManager.gets(DEFAULT_FONT_SET));
			FONTS.put("serif", FontManager.gets(SERIF_FONT_SET));
			FONTS.put("cursive", FontManager.gets(CURSIVE_FONT_SET));
			FONTS.put("monospace", FontManager.gets(MONOSPACED_FONT_SET));
			FONTS.put("fantasy", FontManager.gets(FANTASY_FONT_SET));
			FONTS.put("emoji", FontManager.gets(EMOJI_FONT_SET));
		}
	}

	public static Font getFont(final String f) {
		return FONTS.getOrDefault(f, FontManager.getFontSet());
	}

	public static class flexFontManagerCache {
		private final AtomicBoolean isInit = new AtomicBoolean();
		private final Map<String, RITFont> FONT_CACHE = FastMaps.map(FONTS.size() * SIZES.size());

		public void init(final renderItGraphicsInterface rgi) {
			if (!rgi.supportsOperations(renderItOperations.RIT_AWT_font_conversion))
				throw new RuntimeException("Failed to generate font cache! (Missing operations)");
			if (!isInit.get()) {
				FONTS.forEach((k, v) -> {
					SIZES.forEach((size, val) -> {
						FONT_CACHE.put(k + "-" + size, rgi.awt_make_font(v).deriveToSize(val));
					});
					FONT_CACHE.put(k, rgi.awt_make_font(v));
				});
				isInit.lazySet(true);
			}
		}

		public RITFont getFont(final String f) {
			return FONT_CACHE.get(f);
		}
	}
}
